home *** CD-ROM | disk | FTP | other *** search
- head 1.5;
- branch ;
- access ;
- symbols ;
- locks shirriff:1.5; strict;
- comment @ * @;
-
-
- 1.5
- date 92.07.21.22.04.56; author shirriff; state Exp;
- branches ;
- next 1.4;
-
- 1.4
- date 92.06.16.21.15.37; author jhh; state Exp;
- branches ;
- next 1.3;
-
- 1.3
- date 92.06.16.20.56.33; author shirriff; state Exp;
- branches ;
- next 1.2;
-
- 1.2
- date 92.05.28.23.24.55; author shirriff; state Exp;
- branches ;
- next 1.1;
-
- 1.1
- date 91.12.18.13.45.18; author shirriff; state Exp;
- branches ;
- next ;
-
-
- desc
- @@
-
-
- 1.5
- log
- @Added check so mopd won't respond to a non-sprite machine.
- Added more debugging information.
- Changed handling of out-of-sequence packets so they get dropped on the
- floor. Attempting to respond to out-of-sequence packets caused the
- server to fall behind, so it was responding to the wrong packet and never
- got back in sync.
- @
- text
- @/*
- * MOP server daemon.
- */
-
- #include <stdio.h>
- #include <sys/file.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <net/if_arp.h>
- #include <netinet/if_ether.h>
- #include <netEther.h>
- #ifndef mip
- #define mips 1
- #define notreallymips
- #endif
- #ifndef LANGUAGE_C
- #define LANGUAGE_C
- #endif
- #ifndef MIPSEL
- #define MIPSEL
- #endif
- #include <ds3100.md/sys/exec.h>
- #ifdef notreallymips
- #undef mips
- #endif
- #include <host.h>
- #include <mopd.h>
- #include <signal.h>
- #include <varargs.h>
- #include <time.h>
- #include <string.h>
-
- Net_EtherAddress myAddr;
- Net_EtherAddress multiAddr;
-
- unsigned char broadcast[] = MOP_BROADCAST;
-
- int debug = 0; /* Flag for debug mode. */
-
- extern int errno;
-
- #define WAITING 0
- #define SENDING 1
- #define DONE 2
-
- int mode=WAITING; /* The state we're in. */
- int seq, seqHi; /* The current sequence number. */
- int bootFd; /* The boot program fd. */
- int mopFd; /* The mop device fd. */
- u_char client[6]; /* The client we're dealing with. */
- int loadAddr, length, startAddr, fileOffset; /* Boot file parameters. */
- char filename[100];
-
- static void log();
- int timer();
-
- #if 0
- static char *mopdlog = "/sprite/admin/mopdlog";
- static char *openFlags = "a+";
- #else
- static char *mopdlog = "/dev/syslog";
- static char *openFlags = "w";
- #endif
-
- void
- main(argc,argv)
- int argc;
- char **argv;
- {
- unsigned char buf[BUF_LEN];
- int len;
- u_char us[6], them[6];
- char myName[50];
- mopHdr *mopHdrPtr = (mopHdr *)buf;
- Host_Entry *myEntry, *theirEntry;
- Net_Address theirNetAddress;
- int i;
-
- multiAddr = * (Net_EtherAddress *) broadcast;
- if (gethostname(myName,50)<0) {
- perror("gethostname");
- exit(-1);
- }
- myEntry = Host_ByName(myName);
- if (myEntry == NULL) {
- perror("Host_ByName");
- exit(-1);
- }
- for (i = 0; i < myEntry->numNets; i++) {
- if (myEntry->nets[i].netAddr.type == NET_ADDRESS_ETHER) {
- (void) Net_GetAddress(&myEntry->nets[i].netAddr,
- (Address) &myAddr);
- break;
- }
- }
- Host_End();
- for (argc--, argv++ ; argc > 0 ; argc--, argv++) {
- if (argv[0][0] == '-') {
- switch (argv[0][1]) {
- case 'd':
- debug++;
- break;
- }
- }
- }
-
- if (debug==0) {
- if (fork()) exit(0);
- }
-
- signal(SIGALRM, timer);
-
- mopFd = open(MOP_DEVICE, O_RDWR, 0);
- if (mopFd < 0) {
- perror(MOP_DEVICE);
- exit(-1);
- }
-
- log("Mop server %s starting", myName);
-
- #define US mopHdrPtr->header.ether_dhost
- #define THEM mopHdrPtr->header.ether_shost
- while (1) {
- len = read(mopFd, buf, 1000);
-
- if (debug>1) {
- log("Packet from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x to %2.2x:%2.2x:%2.2x:%2.2x.", THEM[0],THEM[1],THEM[2],THEM[3],THEM[4],THEM[5], US[0],
- US[1], US[2],US[3],US[4],US[5]);
- }
-
- if (!bcmp(&multiAddr, US, sizeof(Net_EtherAddress))) {
- if (debug) {
- log("Got a broadcast packet");
- }
- Host_Start();
- theirNetAddress.type = NET_ADDRESS_ETHER;
- bcopy(THEM,&theirNetAddress.address.ether,
- sizeof(Net_EtherAddress));
- theirEntry = Host_ByNetAddr(&theirNetAddress);
- Host_End();
- if (theirEntry == NULL) {
- log("Packet from unknown %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
- THEM[0],THEM[1],THEM[2],THEM[3],THEM[4],THEM[5]);
- continue;
- }
- } else if (bcmp(&myAddr, US, sizeof(Net_EtherAddress))) {
- log("Mystery packet to %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
- US[0],US[1],US[2],US[3],US[4],US[5]);
- continue;
- }
-
- if (debug>2) {
- log("Received: %d", mopHdrPtr->code);
- }
-
- if (mode == WAITING) {
- bcopy(THEM,client,6);
- } else if (bcmp(client, THEM,6)!=0) {
- /*
- * We can't handle two clients at once, so this one must wait.
- */
- if (debug) {
- log("Mop request collision");
- }
- continue;
- }
-
- if (mopHdrPtr->code == MOP_REQ) {
- if (initRequest(buf)<0) continue;
- }
- if (mode==SENDING && (mopHdrPtr->code == MOP_REQ_LOAD ||
- mopHdrPtr->code == MOP_REQ)) {
- alarm(5);
- sendData(buf);
- } else if (mode==DONE && mopHdrPtr->code == MOP_REQ_LOAD) {
- if (debug) {
- mopReqLoad *mopReqLoadPtr = (mopReqLoad *)(buf+HDR_LEN);
- log("Load completed: status %d", mopReqLoadPtr->error);
- }
- alarm(0);
- close(bootFd);
- mode = WAITING;
- } else {
- log("Out of order function: %d", mopHdrPtr->code);
- if (mode==1) {
- close(bootFd);
- }
- mode = WAITING;
- }
- }
- }
-
- /*
- * Transmit a packet.
- */
- mopXmit(fd, src, dst, len, code, buf)
- int fd;
- u_char *src;
- u_char *dst;
- int len;
- int code;
- char *buf;
- {
- short shortVal;
- mopHdr *mopHdrPtr = (mopHdr *)buf;
- if (debug>2) {
- log("Transmitting: code %d, len: %d", code, len);
- }
- bcopy(src, mopHdrPtr->header.ether_shost, 6);
- bcopy(dst, mopHdrPtr->header.ether_dhost, 6);
- shortVal = SWAP2(NET_ETHER_MOP);
- bcopy(&shortVal, &mopHdrPtr->header.ether_type, sizeof(short));
- shortVal = len+1; /* One byte for the code */
- bcopy(&shortVal, &mopHdrPtr->len, sizeof(short));
- mopHdrPtr->code = code;
- if (write(fd, buf, HDR_LEN+len)<0) {
- log("MOP packet write error: %d", errno);
- }
- }
-
- /*
- * Find how much code we should give the client.
- */
- int
- findStart(inFd, fileOffset, loadAddr, progLen, startAddr)
- int inFd; /* Fd for us to use */
- int *fileOffset; /* Return: offset of program in file. */
- int *loadAddr; /* Return: address to load program. */
- int *progLen; /* Return: the length of the program. */
- int *startAddr; /* Return: start of execution. */
- {
- struct filehdr fileHdr;
- struct aouthdr aoutHdr;
-
- read(inFd, &fileHdr, sizeof(struct filehdr));
- read(inFd, &aoutHdr, sizeof(struct aouthdr));
- aoutHdr.magic = UNSWAP2(aoutHdr.magic);
- aoutHdr.vstamp = UNSWAP2(aoutHdr.vstamp);
- aoutHdr.text_start = UNSWAP4(aoutHdr.text_start);
- aoutHdr.tsize = UNSWAP4(aoutHdr.tsize);
- aoutHdr.dsize = UNSWAP4(aoutHdr.dsize);
- aoutHdr.entry = UNSWAP4(aoutHdr.entry);
- fileHdr.f_magic = UNSWAP2(fileHdr.f_magic);
- fileHdr.f_nscns = UNSWAP2(fileHdr.f_nscns);
- if (fileHdr.f_magic != MIPSELMAGIC || aoutHdr.magic != OMAGIC) {
- log("Bad magic number on boot file %s", filename);
- log("f_magic = %x, want %x. a_magic = %x, want %x",
- fileHdr.f_magic, MIPSELMAGIC, aoutHdr.magic, OMAGIC);
- }
- *fileOffset = N_TXTOFF(fileHdr, aoutHdr);
- *loadAddr = aoutHdr.text_start;
- *progLen = aoutHdr.tsize+aoutHdr.dsize;
- *startAddr = aoutHdr.entry;
- if (debug) {
- log("File: offset: %x, addr: %x, len: %x, start: %x\n", *fileOffset,
- *loadAddr, *progLen, *startAddr);
- }
- }
-
- /*
- * Open our input file.
- */
- int
- openFile(mopPtr)
- mopReq *mopPtr;
- {
- int bootFd;
- char *machineType;
- char *name;
- char *strPtr;
-
- if (mopPtr->devType == 0x43) {
- machineType = "ds3100.md";
- } else if (mopPtr->devType == 0x5e) {
- machineType = "ds5000.md";
- } else {
- log("Unknown machine type %d", mopPtr->devType);
- return -1;
- }
- name = (mopPtr->softID != '\0') ? &mopPtr->softID : "sprite";
- /*
- * Drop any boot flags.
- */
- strPtr = strchr(name,' ');
- if (strPtr != NULL) {
- *strPtr = '\0';
- }
- sprintf(filename,"%s/%s/%s", BOOT_DIR, machineType, name);
- bootFd = open(filename, O_RDONLY, 0);
- if (debug) {
- log("Booting %s", filename);
- }
- if (bootFd < 0) {
- log("Couldn't open %s", filename);
- /*
- * See if we have an error file we can return.
- */
- sprintf(filename,"%s/%s/%s", BOOT_DIR, machineType, "err");
- bootFd = open(filename, O_RDONLY, 0);
- if (bootFd < 0) {
- return -1;
- }
- }
- return bootFd;
- }
-
- /*
- * log an error message
- *
- */
- static void
- log(va_alist)
- va_dcl
- {
- FILE *fp;
- char *format;
- va_list args;
- time_t now;
- char *t;
-
- va_start(args);
- time(&now);
- t = asctime(localtime(&now));
- /* remove the newline */
- t[24] = '\0';
- if ((fp = fopen(mopdlog, openFlags)) == NULL) {
- perror(mopdlog);
- return;
- }
- fprintf(fp, "[mopd %s]: ", t);
- format = va_arg(args, char *);
- vfprintf(fp, format, args);
- putc('\n', fp);
- fclose(fp);
- return;
- }
-
- /*
- * Handle an initial request.
- */
- initRequest(buf)
- char *buf;
- {
- mopReq *mopPtr = (mopReq *)(buf+HDR_LEN);
-
- if (mode!=WAITING) {
- if (debug) {
- log("Wasn't expecting request");
- }
- }
- seq = 0;
- seqHi = 0;
- bootFd = openFile(mopPtr);
- if (bootFd<0) {
- if (debug) {
- log("openFile failed");
- }
- mode = WAITING;
- return -1;
- }
- mode = SENDING;
- if (findStart(bootFd, &fileOffset, &loadAddr, &length,
- &startAddr)<0) {
- if (debug) {
- log("findStart failed");
- }
- mode = WAITING;
- close(bootFd);
- return -1;
- }
- return 0;
- }
-
- /*
- * Send the next data packet.
- */
- sendData(buf)
- {
- mopHdr *mopHdrPtr = (mopHdr *)buf;
- mopLoad *mopLoadPtr = (mopLoad *)(buf+HDR_LEN);
- mopReqLoad *mopReqLoadPtr = (mopReqLoad *)(buf+HDR_LEN);
- mopParamLoad *mopParamLoadPtr = (mopParamLoad *)(buf+HDR_LEN);
- int intVal;
- int seqReq;
- int curPos, toRead;
- /*
- * Check the sequence numbers.
- */
- if (mopHdrPtr->code == MOP_REQ) {
- seqReq = 0;
- } else {
- seqReq = mopReqLoadPtr->loadNum;
- if (debug) {
- log("Requested sequence number %d\n", seqReq);
- }
- if (mopReqLoadPtr->error != 0) {
- if (debug) {
- log("Load error status %d", mopReqLoadPtr->error);
- }
- mode = WAITING;
- close(bootFd);
- return;
- }
- }
- if (seqReq != seq) {
- log("Out of sequence request %d vs %d from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", seqReq, seq, THEM[0], THEM[1], THEM[2], THEM[3], THEM[4], THEM[5]);
- /* Somehow we need to get back into sync. */
- seq = seqReq;
- return;
- }
- /*
- * Transmit the data.
- */
- curPos = PACKET_SIZE*(seq+seqHi*256);
- toRead = length-curPos;
- if (toRead > PACKET_SIZE) {
- toRead = PACKET_SIZE;
- }
- if (toRead > 0) {
- lseek(bootFd, fileOffset+curPos, 0);
- if (read(bootFd, buf+HDR_LEN+MOPLOAD_LEN, toRead) != toRead) {
- log("Short boot file %s",filename);
- mode = WAITING;
- close(bootFd);
- return;
- }
- mopLoadPtr->loadNum = seq;
- intVal = UNSWAP4((loadAddr + curPos));
- bcopy(&intVal, mopLoadPtr->loadAddr, sizeof(int));
- toRead = PACKET_SIZE; /* HACK */
- mopXmit(mopFd, &myAddr, client, MOPLOAD_LEN+toRead, MOP_LOAD, buf);
- } else {
- mopParamLoadPtr->loadNum = seq;
- mopParamLoadPtr->parameters = 0;
- intVal = UNSWAP4(startAddr);
- if (debug) {
- log("Transferring to %x", startAddr);
- }
- bcopy(&intVal, &mopParamLoadPtr->parameters+1, sizeof(int));
- mopXmit(mopFd, &myAddr, client, sizeof(mopParamLoad)+sizeof(int),
- MOP_PARAM_LOAD_XFER, buf);
- mode = DONE;
- }
- seq++;
- if (seq==256) {
- seq=0;
- seqHi++;
- }
- }
-
- /*
- * Handle a timeout.
- */
- timer()
- {
- if (mode != WAITING) {
- if (debug) {
- log("Timeout");
- }
- close(bootFd);
- mode = WAITING;
- }
- }
- @
-
-
- 1.4
- log
- @port to new Host library
- now uses some of the standard Net stuff
- forgot to call Host_End
- @
- text
- @d75 2
- a76 1
- Host_Entry *myEntry;
- d127 2
- a128 1
- log("Packet from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x to %2.2x:%2.2x:%2.2x:%2.2x.", THEM, US);
- d135 11
- d148 1
- a148 1
- US);
- d393 3
- d398 1
- a398 1
- log("Load error");
- d406 1
- a406 1
- log("Out of sequence request %d vs %d from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", seqReq, seq, THEM);
- d409 1
- @
-
-
- 1.3
- log
- @ken fixed a printf -- jhh
- @
- text
- @d33 2
- a34 2
- unsigned char myAddr[HOST_ETHER_ADDRESS_SIZE];
- unsigned char multiAddr[HOST_ETHER_ADDRESS_SIZE] = MOP_BROADCAST;
- d36 2
- d76 1
- d78 1
- d88 8
- a95 2
- bcopy(myEntry->netAddr.etherAddr,myAddr, HOST_ETHER_ADDRESS_SIZE);
-
- d129 1
- a129 1
- if (!bcmp(multiAddr, US, HOST_ETHER_ADDRESS_SIZE)) {
- d133 1
- a133 1
- } else if (bcmp(myAddr, US, HOST_ETHER_ADDRESS_SIZE)) {
- d414 1
- a414 1
- mopXmit(mopFd, myAddr, client, MOPLOAD_LEN+toRead, MOP_LOAD, buf);
- d423 1
- a423 1
- mopXmit(mopFd, myAddr, client, sizeof(mopParamLoad)+sizeof(int),
- @
-
-
- 1.2
- log
- @Increased timeout length, so mop doesn't time out on slow systems.
- Added feature to boot an error file if the file doesn't exist.
- (This file prints "file not found").
- @
- text
- @d307 1
- a307 1
- fprintf(fp, "[%s]: ", t);
- d381 1
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @d150 1
- a150 1
- alarm(2);
- d272 8
- a279 1
- return -1;
- @
-